/**
 * Creat with IntelliJ IDEA
 * Description:单例模式
 * User:WZW
 * Date:2022-09-08
 * Time:19:45
 */
public class Demo20 {

    // 饿汉模式
    static class Singleton {
        // static修饰的变量，称为类成员(类属性/类方法)
        // 一个Java程序中，一个类对象只有一份，因此static成员也只有一份
        private static Singleton instance = new Singleton();
        // 构造方法设置为private，防止程序员在其他地方new这个Singleton
        private Singleton() { }
        // 提供一个方法使外面能够拿到这个唯一实例
        public static Singleton getInstance() {
            return instance;
        }
    }

    // 懒汉模式
    static class Singleton2 {
        private static Singleton2 instance = null;
        private Singleton2() { }
        // 只有当需要该实例的时候，才创建实例
        public static Singleton2 getInstance() {
            if (instance == null) {
                instance = new Singleton2();
            }
            return instance;
        }
    }

    static class Singleton3 {
        // 加上volatile保证内存可见性
        private static volatile Singleton3 instance = null;
        private Singleton3() { }
        // 只有当需要该实例的时候，才创建实例
        public synchronized static Singleton3 getInstance() {
            // 外层if保证实例已经创建出来之后，直接返回实例，不会存在锁竞争
            if (instance == null) {
                // 实例还没创建出来的时候，加锁保证线程安全
                synchronized (Singleton3.class) {
                    if (instance == null) {
                        instance = new Singleton3();
                    }
                }
            }
            return instance;
        }
    }

}
